package com.kikt.custombtndemo.http;

import android.support.annotation.NonNull;
import android.util.Log;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.Collections;
import java.util.Map;

import okhttp3.Call;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * Created by kikt on 2016/5/7.
 * 网络访问的框架
 */
public abstract class PostJsonRequest {
    protected final String url;
    protected final String body;
    public static final OkHttpClient okHttpClient = new OkHttpClient();
    protected Map<String, String> map = Collections.emptyMap();
    protected long timeOut;
    protected Call call;

    public PostJsonRequest(String url, String body) {
        this.url = fixUrl(url);
        this.body = body;
    }

    private String fixUrl(String url) {
        String prefix = "http://";
        if (!url.startsWith(prefix)) {
            url = prefix + url;
        }
        return url;
    }

    protected void onResponse() {

    }

    protected abstract void onNetError(HttpError ex);

    protected abstract void onStatusError(String msg, String errorCode);

    protected abstract void onSuccess(String json);

    public void start() {
        String body = getBody();
        Log.d("PostJsonRequest", body);
        RequestBody requestBody = createBody(body);
        Request.Builder builder = new Request.Builder().url(url).headers(getHeader()).method("POST", requestBody);
        call = okHttpClient.newCall(builder.build());
        new Thread() {
            @Override
            public void run() {
                try {
                    Response response = call.execute();
                    Log.d("PostJsonRequest", response.body().string());
                    onResponse();
                    int code = response.code();
                    if (code == 200) {
                        success(response);
                    } else {
//                        Log.e("httpError:", "url=" + url + "\nmsg:" + response.body().string());
                        onNetError(new HttpError(code + ""));
                    }
                } catch (IOException e) {
                    Log.e("httpError:", "url=" + url);
                    onResponse();
                    onNetError(new HttpError(e));
                }
            }
        }.start();
    }

    @NonNull
    protected RequestBody createBody(String body) {
        return RequestBody.create(getType(), body);
    }

    protected void success(Response response) {
        try {
            JSONObject object = new JSONObject(response.body().string());
            int status = object.optInt("status");
            if (status == 200) {
                onSuccess(response.body().string());
            } else {
                String msg = object.optString("msg");
                onStatusError(msg, String.valueOf(status));
            }
        } catch (JSONException e) {
            onNetError(new HttpError(e));
        } catch (IOException e) {
            onNetError(new HttpError(e));
        }
    }

    protected MediaType getType() {
        return MediaType.parse("application/json; charset=utf-8");
    }

    protected String getBody() {
        return encodeBody(body);
    }

    protected String encodeBody(String body) {
        return "test:" + body;
    }

    public void setHeader(Map<String, String> map) {
        this.map = map;
    }

    public void setTimeOut(long timeMillis) {
        this.timeOut = timeMillis;
    }

    private Headers getHeader() {
        Headers.Builder builder = new Headers.Builder();
        for (Map.Entry<String, String> entry : map.entrySet()) {
            builder.add(entry.getKey(), entry.getValue());
        }
        return builder.build();
    }

    public void cancel() {
        if (call != null) {
            call.cancel();
        }
    }
}
